package pers.qianyu.controller;

import io.swagger.annotations.*;
import lombok.extern.slf4j.*;
import org.springframework.beans.factory.annotation.*;
import org.springframework.cache.annotation.*;
import org.springframework.validation.annotation.*;
import org.springframework.web.bind.annotation.*;
import pers.qianyu.domain.common.*;
import pers.qianyu.domain.dto.*;
import pers.qianyu.domain.vo.*;
import pers.qianyu.exception.*;
import pers.qianyu.service.*;
import pers.qianyu.util.*;

import javax.validation.constraints.*;

/**
 * @author mizzle rain
 * @date 2020-10-11 22:15
 */
@Api(value = "用户相关接口", protocols = "http,https")
@Slf4j
// 开启对基础类型的校验
@Validated
@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;
    @Autowired
    private ExcelExportService excelExportService;

    /**
     * 新建用户
     *
     * @param userDTO 要插入的用户信息
     * @return 响应结果
     */
    @ApiOperation(value = "新增用户", notes = "以POST请求的形式传入用户数据")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "userDTO",
                    value = "用户信息",
                    required = true,
                    paramType = "body",
                    dataType = "UserDTO",
                    dataTypeClass = UserDTO.class
            )
    })
    @PostMapping
    @CacheEvict(cacheNames = "users-cache", allEntries = true)
    public HttpResult save(@Validated(InsertValidationGroup.class) @RequestBody UserDTO userDTO) {
        int save = userService.save(userDTO);
        if (save == 1) {
            return HttpResult.okWithMessage("新增用户成功");
        } else {
            return HttpResult.error(ErrorCodeEnum.INSERT_FAILURE);
        }
    }

    /**
     * 更新用户信息
     *
     * @param id      用户 id
     * @param userDTO 更新的用户信息
     * @return 响应结果
     */
    @ApiOperation(value = "更新用户信息", notes = "路径参数为 id ，请求body 为更新的信息")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "id",
                    value = "用户主键",
                    required = true,
                    paramType = "path",
                    dataType = "Long",
                    example = "23"
            ),
            @ApiImplicitParam(
                    name = "userDTO",
                    value = "用户信息",
                    required = true,
                    paramType = "body",
                    dataType = "UserDTO",
                    dataTypeClass = UserDTO.class
            )
    })
    @PutMapping("/{id}")
    public HttpResult update(@NotNull(message = "用户 ID 不能为空") @PathVariable("id") Long id,
                             @Validated(UpdateValidationGroup.class) @RequestBody UserDTO userDTO) {
        int update = userService.update(id, userDTO);
        if (update == 1) {
            return HttpResult.okWithMessage("更新用户成功");
        } else {
            return HttpResult.error(ErrorCodeEnum.UPDATE_FAILURE);
        }
    }

    /**
     * 删除用户信息
     *
     * @param id 要删除的用户信息
     * @return 响应结果
     */
    @ApiOperation(value = "根据 id 删除用户", notes = "传入用户 id 删除对应用户")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "id",
                    value = "用户id",
                    required = true,
                    paramType = "path",
                    dataType = "Long"
            )
    })
    @DeleteMapping("/{id}")
    public HttpResult delete(@NotNull(message = "用户 id 不能为空") @PathVariable("id") Long id) {
        int delete = userService.delete(id);
        if (delete == 1) {
            return HttpResult.okWithMessage("删除用户成功");
        } else {
            return HttpResult.error(ErrorCodeEnum.DELETE_FAILURE);
        }
    }

    /**
     * 查询用户信息
     *
     * @param page         页码
     * @param limit        页面大小
     * @param userQueryDTO 查询条件
     * @return 响应结果
     */
    @ApiOperation(value = "分页查询用户信息", notes = "根据页码、页面大小、查询条件查询用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "page",
                    value = "页码",
                    required = false,
                    defaultValue = "1",
                    paramType = "query",
                    dataType = "Integer"
            ),
            @ApiImplicitParam(
                    name = "limit",
                    value = "页面大小",
                    required = false,
                    defaultValue = "5",
                    paramType = "query",
                    dataType = "Integer"
            ),
            @ApiImplicitParam(
                    name = "userQueryDTO",
                    value = "查询条件",
                    required = false,
                    paramType = "query",
                    dataType = "UserQueryDTO",
                    dataTypeClass = UserQueryDTO.class
            )
    })
    @Cacheable(cacheNames = "users-cache")
    @GetMapping
    public HttpResult<Pagination<UserVO>> query(UserQueryDTO userQueryDTO) {
        log.info("未使用缓存...");
        Pagination<UserVO> pagination = userService.query(userQueryDTO);
        return HttpResult.okWithData(pagination);
    }

    /**
     * 导出数据库中用户信息
     *
     * @param userQueryDTO 查询条件
     * @param fileName     导出的文件名
     * @return 相应结果
     */
    @ApiOperation(value = "导出用户信息", notes = "将用户信息导出为 Excel")
    @ApiImplicitParams({
            @ApiImplicitParam(
                    name = "userQueryDTO",
                    value = "查询条件",
                    required = false,
                    paramType = "query",
                    dataType = "UserQueryDTO",
                    dataTypeClass = UserQueryDTO.class
            ),
            @ApiImplicitParam(
                    name = "fileName",
                    value = "导出的文件名",
                    required = true,
                    paramType = "query",
                    dataType = "String"
            )
    })
    @GetMapping("/export")
    public HttpResult<Boolean> export(UserQueryDTO userQueryDTO,
                                      @NotEmpty(message = "文件名不能为空") String fileName) {
        // excelExportService.export(userQueryDTO, fileName);
        excelExportService.asyncExport(userQueryDTO, fileName);
        return HttpResult.okWithData(Boolean.TRUE);
    }
}
